#include "Cursor.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>
#include <iostream>
using namespace std;

Cursor::Cursor(CubePileGrid * aCubePiles)
{
	cubePiles = aCubePiles;
	xPos = 0;
	zPos = 0;
	xInd = 0;
	zInd = 0;
	mouseX = 0;
	mouseY = 0;
}

Cursor::~Cursor()
{
	
}

void hardColor()
{
	glColor4f(1.0f,1.0f,0.0f, 0.6f);			// Full Brightness, 50% Alpha ( NEW )	
}

void softColor()
{
	glColor4f(1.0f,1.0f,0.0f, 0.01f);			// Full Brightness, 50% Alpha ( NEW )	
}

void Cursor::render()
{
	calculatePosition();
	
	glEnable(GL_BLEND);
	glTranslatef(xPos, 0, zPos);
	
	glBegin(GL_QUADS);
	
		//front face
		hardColor();
		glVertex3f(-1, 0.5, 0.9);
		glVertex3f( 1, 0.5, 0.9);
		glVertex3f( 1,-0.5, 0.9);
		glVertex3f(-1,-0.5, 0.9);
		
		//front fade
		softColor();
		glVertex3f(-0.9, 8.0, 0.9);
		glVertex3f( 0.9, 8.0, 0.9);
		hardColor();
		glVertex3f( 0.9, 0.5, 0.9);
		glVertex3f(-0.9, 0.5, 0.9);
		
		//back face
		glVertex3f( 1.0f,-0.5f,-1.0f);			// Bottom Left Of The Quad (Back)
		glVertex3f(-1.0f,-0.5f,-1.0f);			// Bottom Right Of The Quad (Back)
		glVertex3f(-1.0f, 0.5f,-1.0f);			// Top Right Of The Quad (Back)
		glVertex3f( 1.0f, 0.5f,-1.0f);			// Top Left Of The Quad (Back)
		
		//back fade
		glVertex3f( 1.0f,-0.5f,-1.0f);			// Bottom Left Of The Quad (Back)
		glVertex3f(-1.0f,-0.5f,-1.0f);			// Bottom Right Of The Quad (Back)
		softColor();
		glVertex3f(-1.0f, 8.0f,-1.0f);			// Top Right Of The Quad (Back)
		glVertex3f( 1.0f, 8.0f,-1.0f);			// Top Left Of The Quad (Back)
		
		//right face
		hardColor();
		glVertex3f( 1.0f, 0.5f,-1.0f);			// Top Right Of The Quad (Right)
		glVertex3f( 1.0f, 0.5f, 1.0f);			// Top Left Of The Quad (Right)
		glVertex3f( 1.0f,-0.5f, 1.0f);			// Bottom Left Of The Quad (Right)
		glVertex3f( 1.0f,-0.5f,-1.0f);			// Bottom Right Of The Quad (Right)
		
		//right fade
		softColor();
		glVertex3f( 1.0f, 8.0f,-1.0f);			// Top Right Of The Quad (Right)
		glVertex3f( 1.0f, 8.0f, 1.0f);			// Top Left Of The Quad (Right)
		hardColor();
		glVertex3f( 1.0f,-0.5f, 1.0f);			// Bottom Left Of The Quad (Right)
		glVertex3f( 1.0f,-0.5f,-1.0f);			// Bottom Right Of The Quad (Right)
		
		//left face
		glVertex3f(-1.0f, 0.5f, 1.0f);			// Top Right Of The Quad (Left)
		glVertex3f(-1.0f, 0.5f,-1.0f);			// Top Left Of The Quad (Left)
		glVertex3f(-1.0f,-0.5f,-1.0f);			// Bottom Left Of The Quad (Left)
		glVertex3f(-1.0f,-0.5f, 1.0f);			// Bottom Right Of The Quad (Left)
		
		//left fade
		softColor();
		glVertex3f(-1.0f, 8.0f, 1.0f);			// Top Right Of The Quad (Left)
		glVertex3f(-1.0f, 8.0f,-1.0f);			// Top Left Of The Quad (Left)
		hardColor();
		glVertex3f(-1.0f,-0.5f,-1.0f);			// Bottom Left Of The Quad (Left)
		glVertex3f(-1.0f,-0.5f, 1.0f);			// Bottom Right Of The Quad (Left)
		
	glEnd();
	glTranslatef(-xPos, 0, -zPos);
	glDisable(GL_BLEND);
}

void Cursor::calculatePosition()
{
	GLuint buffer [PICK_BUFFER_SIZE];
	
	glSelectBuffer(PICK_BUFFER_SIZE, buffer);
	glRenderMode(GL_SELECT);
	
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	
	GLint viewPort[4];
	glGetIntegerv(GL_VIEWPORT, viewPort);
	gluPickMatrix(mouseX, viewPort[3] - mouseY, PICK_SIZE, PICK_SIZE, viewPort);
	
	gluPerspective(45, (float)WINDOW_WIDTH / WINDOW_HEIGHT, 0.1, 100);
	glMatrixMode(GL_MODELVIEW);
	glInitNames();
	
	for( int i=0; i<GRID_SIZE; i++)
	{
		glPushName(i);
		for( int j=0; j<GRID_SIZE; j++)
		{
			glPushName(j);
			cubePiles->at(i,j)->renderBottom();
			glPopName();
		}
		glPopName();
	}
	
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glFlush();
	int hits = glRenderMode(GL_RENDER);
	if (hits != 0)
	{
		GLuint names, *ptr, minZ, *ptrNames, numberOfNames;
		ptr = (GLuint *)buffer;
		minZ = 0xffffffff;
		for(int i=0; i<hits; i++)
		{
			names = *ptr;
			ptr++;
			if(*ptr < minZ)
			{
				numberOfNames = names;
				minZ = *ptr;
				ptrNames = ptr+2;
			}
			ptr += names + 2;
		}
		if(numberOfNames == 2)
		{
			ptr = ptrNames;
		
			xInd = *ptr;
			ptr++;
			zInd = *ptr;
			
			Cube * topCube = getCurrentPile()->peekAtTop();
			xPos = topCube->xPos;
			zPos = topCube->zPos;
		}
	}
}

CubePile * Cursor::getCurrentPile()
{
	return cubePiles->at(xInd,zInd);
}


void Cursor::checkBounds()
{
	if(xInd < 0)
	{
		xInd = 0;
	}
	if (xInd >= GRID_SIZE)
	{
		xInd = GRID_SIZE -1;
	}
	if (zInd < 0)
	{
		zInd = 0;
	}
	if(zInd >= GRID_SIZE)
	{
		zInd = GRID_SIZE -1;
	}
}

void Cursor::handleEvent(bool keys[321])
{
	if(keys[SDLK_UP])
	{
		zInd--;
	}
	if(keys[SDLK_DOWN])
	{
		zInd++;
	}
	if(keys[SDLK_RIGHT])
	{
		xInd++;
	}
	if(keys[SDLK_LEFT])
	{
		xInd--;
	}
}

void Cursor::handleEvent(SDL_Event * event)
{
	if( event->type == SDL_MOUSEMOTION )
	{
		//Get the mouse offsets x = event.motion.x; y = event.motion.y;
		mouseX = event->motion.x;
		mouseY = event->motion.y;
	}	
}
